/** \file    xmlspirit.h
  * \brief   Implementation of our xml serializer based on Boost::Spirit parser.
  * \date    2003
  * \author  Fedor Chelnokov
  * \version $Header: /home/cscom1r4/cvsroot/cs/include/xml/spirit.h,v 1.2 2004/06/24 16:47:41 cscom1r4 Exp $
  */

#ifndef _xmlspirit_h_
#define _xmlspirit_h_

#include <map>
#include <vector>
#include <iostream>
#include "xml/impl.h"

#ifdef XMLSPIRIT_IMPL
#	define XMLSPIRIT_DLLAPI __declspec(dllexport)
#else
#	define XMLSPIRIT_DLLAPI __declspec(dllimport)
/* Pasha: name of the lib depends on the project version :(
#	ifdef _DEBUG
#		pragma comment(lib, "xmlspiritd.lib")
#	else
#		pragma comment(lib, "xmlspirit.lib")
#	endif
*/
#endif


namespace xml {

class spirit_attr_enum;
class spirit_child_enum;
class spirit_tag_enum;
class spirit_buider;
class write_element;

class spirit : public implementation {
public:
	XMLSPIRIT_DLLAPI spirit();
	XMLSPIRIT_DLLAPI ~spirit();
public:
	XMLSPIRIT_DLLAPI void clear();
	XMLSPIRIT_DLLAPI void create(const string & root_tag);
	XMLSPIRIT_DLLAPI void parse(const string & xmlstream);
	XMLSPIRIT_DLLAPI void read(const string & filename);
	XMLSPIRIT_DLLAPI void write(const string & filename);
	XMLSPIRIT_DLLAPI void write(std::ostream & s);
	XMLSPIRIT_DLLAPI const_node root() const;
	XMLSPIRIT_DLLAPI node root();
private:
	// handle management
	virtual handle copy(handle h);
	virtual void release(handle h);
	virtual bool null(handle h);
	// tag access
	virtual string get_tag(handle h);
	// attribute access
	virtual attribute_enumeration * get_attributes(handle h);
	virtual bool get_attribute(handle h, const string & name, string & value);
	virtual void set_attribute(handle h, const string & name, const string & value);
	// children access
	virtual node_enumeration * get_children(handle h);
	virtual node_enumeration * get_children_by_tag(handle h, const string & tag);
	// creation/deletion
	virtual handle create_child(handle h, const string & tag);
	virtual void clear(handle h, bool attr, bool children);
	virtual void erase(handle h);
public:
	class element;
	typedef std::map<string, string> attrs_type;
	typedef std::vector<element*> children_type; //assume that child delete is rare operation
private:
	element * _root;
	friend class spirit_buider;
public: //for internal usa only
	class element {
		element * const _parent;
		const string _tag;
		attrs_type _attrs;
		children_type _children;
	public:
		inline element(element * p, const string & t);
		inline ~element();
	public:
		inline element * parent();
		inline const string & tag() const;
		inline attribute_enumeration * get_attributes() const;
		inline bool get_attribute(const string & name, string & value) const;
		inline void set_attribute(const string & name, const string & value);
		inline node_enumeration * get_children();
		inline node_enumeration * get_children_by_tag(const string & tag);
		inline handle create_child(const string & tag);
		inline void clear(bool attr, bool children);
		inline void erase();
	private:
		inline void erase(element * child);
	private:
		friend class spirit_attr_enum;
		friend class spirit_child_enum;
		friend class spirit_tag_enum;
		friend class write_element;
	};
};

} //namespace xml

#endif //_xmlspirit_h_
